<?php

namespace services\log;

use api\modules\v1\forms\member\MemberForm;
use api\modules\v1\forms\rbac\ActionForm;
use api\modules\v1\forms\rbac\MenuForm;
use api\modules\v1\forms\rbac\RoleForm;
use common\components\Service;
use common\helpers\ArrayHelper;
use common\helpers\CommonHelper;
use common\helpers\RedisHelper;
use common\models\base\TreatmentProject;
use common\models\log\LogMemberOp;
use common\models\member\Member;
use common\models\patient\Patient;
use common\models\patient\PatientType;
use common\models\rbac\Action;
use common\models\rbac\Menu;
use common\models\rbac\Role;
use common\models\spoker\Spoker;
use common\models\system\SystemConfig;
use common\models\user\UserFeedback;
use services\member\MemberService;
use services\rbac\ActionService;
use services\rbac\MenuService;
use services\rbac\RoleService;
use Yii;
use yii\db\ActiveRecord;

class LogMemberOpService extends Service
{
    /**
     * 查询是否存在操作
     * @param int $type
     * @param $relationIds
     * @return array|ActiveRecord[]
     */
    public static function getLogMemberOpListExist(int $type, $relationIds)
    {
        return LogMemberOp::find()
            ->select(['relation_id'])
            ->where([
                'relation_id' => $relationIds,
                'type' => $type,
            ])
            ->groupBy('relation_id')
            ->indexBy('relation_id')
            ->all();
    }

    /**
     * 新增日志
     * @param int $relationId
     * @param string $content
     * @param int $type
     * @param int $memberId =0系统 >0用户
     * @return LogMemberOp
     * @throws \Exception
     */
    public static function create(int $relationId, string $content, int $type, int $memberId = 0): LogMemberOp
    {
        $logMemberOp = new LogMemberOp();
        $logMemberOp->member_id = $memberId;
        $logMemberOp->relation_id = $relationId;
        $logMemberOp->content = $content;
        $logMemberOp->type = $type;
        $logMemberOp->saveAndCheckResult();
        return $logMemberOp;
    }

    /**
     * 是否修改model
     * @param ActiveRecord $old
     * @param ActiveRecord $new
     * @param array $column
     * @return bool
     */
    public static function isEditModel(ActiveRecord $old, ActiveRecord $new, array $column = []): bool
    {
        if (empty($column)) {
            return false;
        }
        foreach ($column as $item) {
            if (is_string($old[$item]) || is_numeric($old[$item])) {
                $old[$item] = (string)$old[$item];
            }
            if (is_string($new[$item]) || is_numeric($new[$item])) {
                $new[$item] = (string)$new[$item];
            }
            if ($old[$item] !== $new[$item]) {
                return true;
            }
        }
        return false;
    }

    /**
     * 人员操作日志
     * @param MemberForm $model
     * @param Member $new
     * @param Member|null $old
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createMemberLog(MemberForm $model, Member $new, ?Member $old = null): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($model->getScenario()) {
            case 'create':
            case 'edit':
                $statusStr = Member::$statuss[$new->status] ?? '';
                $roles = $model->getRoleList();
                $roleNameArr = array_column($roles, 'name');
                $roleNameStr = $roleNameArr ? implode(',', $roleNameArr) : '';
                $optionStr = "【用户名：{$new->username} 手机号：{$new->mobile} 角色：{$roleNameStr} 状态：{$statusStr}】";
                if ($model->getScenario() == 'create') {
                    $type = LogMemberOp::TYPE_MEMBER_CREATE;
                    $content = "新增人员;{$optionStr}";
                } else {
                    $type = LogMemberOp::TYPE_MEMBER_UPDATE;
                    if (self::isEditModel($old, $new, ['username', 'mobile', 'status'])
                        || ArrayHelper::isArrEqual(array_column($roles, 'id'), $model->getOldRoleIds()) === false
                    ) {// 存在修改
                        $oldStatusStr = Member::$statuss[$old->status] ?? '';
                        $oldRoles = RoleService::getNormalCacheListByIds($model->getOldRoleIds());
                        $oldRoleNameArr = array_column($oldRoles, 'name');
                        $oldRoleNameStr = $oldRoleNameArr ? implode(',', $oldRoleNameArr) : '';
                        $content = "编辑人员;由【用户名：{$old->username} 手机号：{$old->mobile} 角色：{$oldRoleNameStr} 状态：{$oldStatusStr}】更改为{$optionStr}";
                    }
                }
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_MEMBER_DELETE;
                $content = "删除人员;【用户名：{$new->username}】";
                break;
            case 'update_password':
                $type = LogMemberOp::TYPE_MEMBER_UPDATE_PASSWORD;
                $content = "主动修改密码;【用户名：{$new->username}】";
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 动作操作日志
     * @param ActionForm $model
     * @param Action $new
     * @param Action|null $old
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createActionLog(ActionForm $model, Action $new, ?Action $old = null): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($model->getScenario()) {
            case 'create':
            case 'edit':
                $statusStr = Action::$statuss[$new->status] ?? '';
                $menuName = $model->getMenu()->name ?? '';
                $optionStr = "【动作：{$new->name} 菜单：{$menuName} 路由：{$new->flag} 排序：{$new->sort} 状态：{$statusStr}】";
                if ($model->getScenario() == 'create') {
                    $type = LogMemberOp::TYPE_ACTION_CREATE;
                    $content = "新增动作;{$optionStr}";
                } else {
                    $type = LogMemberOp::TYPE_ACTION_UPDATE;
                    if (self::isEditModel($old, $new, ['menu_id', 'name', 'flag', 'sort', 'status'])) {// 存在修改
                        $oldStatusStr = Action::$statuss[$old->status] ?? '';
                        $oldMenuName = RedisHelper::getMenu($old->menu_id)->name ?? '';
                        $content = "编辑动作;由【动作：{$old->name} 菜单：{$oldMenuName} 路由：{$old->flag} 排序：{$old->sort} 状态：{$oldStatusStr}】更改为{$optionStr}";
                    }
                }
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_ACTION_DELETE;
                $content = "删除动作;【动作：{$new->name}】";
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 菜单操作日志
     * @param MenuForm $model
     * @param Menu $new
     * @param Menu|null $old
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createMenuLog(MenuForm $model, Menu $new, ?Menu $old = null): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($model->getScenario()) {
            case 'create':
            case 'edit':
                $statusStr = Menu::$statuss[$new->status] ?? '';
                $pMenuName = $model->getParentMenu()->name ?? '';
                $optionStr = "【菜单：{$new->name} 父菜单：{$pMenuName} 菜单url：{$new->url} 菜单icon：{$new->class_style} 排序：{$new->sort} 状态：{$statusStr}】";
                if ($model->getScenario() == 'create') {
                    $type = LogMemberOp::TYPE_MENU_CREATE;
                    $content = "新增菜单;{$optionStr}";
                } else {
                    $type = LogMemberOp::TYPE_MENU_UPDATE;
                    if (self::isEditModel($old, $new, ['name', 'parent_menu_id', 'url', 'class_style', 'sort', 'status'])) {// 存在修改
                        $oldStatusStr = Menu::$statuss[$old->status] ?? '';
                        $oldPMenuName = RedisHelper::getMenu($old->parent_menu_id)->name ?? '';
                        $content = "编辑菜单;由【菜单：{$old->name} 父菜单：{$oldPMenuName} 菜单url：{$old->url} 菜单icon：{$old->class_style} 排序：{$old->sort} 状态：{$oldStatusStr}】更改为{$optionStr}";
                    }
                }
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_MENU_DELETE;
                $content = "删除菜单;【菜单：{$new->name}】";
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 角色操作日志
     * @param RoleForm $model
     * @param Role $new
     * @param Role|null $old
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createRoleLog(RoleForm $model, Role $new, ?Role $old = null): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($model->getScenario()) {
            case 'create':
            case 'edit':
                $statusStr = Role::$statuss[$new->status] ?? '';
                $optionStr = "【角色：{$new->name} 描述：{$new->desc} 状态：{$statusStr}】";
                if ($model->getScenario() == 'create') {
                    $type = LogMemberOp::TYPE_ROLE_CREATE;
                    $content = "新增角色;{$optionStr}";
                } else {
                    $type = LogMemberOp::TYPE_ROLE_UPDATE;
                    if (self::isEditModel($old, $new, ['name', 'desc', 'status'])) {// 存在修改
                        $oldStatusStr = Role::$statuss[$old->status] ?? '';
                        $content = "编辑角色;由【角色：{$old->name} 描述：{$old->desc} 状态：{$oldStatusStr}】更改为{$optionStr}";
                    }
                }
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_ROLE_DELETE;
                $content = "删除角色;【角色：{$new->name}】";
                break;
            case 'edit_permission':
                $type = LogMemberOp::TYPE_ROLE_ALLOT;
                if ($model->getDeleteActionIds() || $model->getAddActionIds() || $model->getDeleteMenuIds() || $model->getAddMenuIds()) {
                    $delActions = ActionService::getNormalCacheListByIds($model->getDeleteActionIds());
                    $addActions = ActionService::getNormalCacheListByIds($model->getAddActionIds());
                    $delMenus = MenuService::getNormalCacheListByIds($model->getDeleteActionIds());
                    $addMenus = MenuService::getNormalCacheListByIds($model->getAddActionIds());

                    $delActionStr = $delActions ? implode(',', array_column($delActions, 'name')) : '';
                    $delMenuStr = $delMenus ? implode(',', array_column($delMenus, 'name')) : '';
                    $addActionStr = $addActions ? implode(',', array_column($addActions, 'name')) : '';
                    $addMenuStr = $addMenus ? implode(',', array_column($addMenus, 'name')) : '';
                    $content = "分配角色权限;【角色：{$new->name} 新增菜单：{$addMenuStr} 新增动作：{$addActionStr} 删除菜单：{$delMenuStr} 删除动作：{$delActionStr}】";
                }
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 创建系统配置操作日志
     * @param SystemConfig $systemConfig
     * @param string $newValue
     * @param string $oldValue
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createSystemConfigLog(SystemConfig $systemConfig, string $newValue, string $oldValue): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        if ($newValue != $oldValue) {
            switch ($systemConfig->name) {
                case SystemConfig::NAME_C_HOME_PAGE_TITLE:
                    $type = LogMemberOp::TYPE_OTHER_HOME_PAGE_TITLE;
                    break;
                case SystemConfig::NAME_C_HOME_PAGE_BANNER_TYPE:
                    $type = LogMemberOp::TYPE_OTHER_HOME_PAGE_BANNER_TYPE;
                    break;
                case SystemConfig::NAME_C_HOME_PAGE_BANNER_IMAGE:
                    $type = LogMemberOp::TYPE_OTHER_HOME_PAGE_BANNER_IMAGE;
                    break;
                case SystemConfig::NAME_C_HOME_PAGE_BANNER_VIDEO:
                    $type = LogMemberOp::TYPE_OTHER_HOME_PAGE_BANNER_VIDEO;
                    break;
                case SystemConfig::NAME_C_HOME_PAGE_BANNER_CONTENT:
                    $type = LogMemberOp::TYPE_OTHER_HOME_PAGE_BANNER_CONTENT;
                    break;
                default:
                    break;
            }
            if ($type) {
                $content = SystemConfig::$names[$systemConfig->name] ?? '';
                if ($systemConfig->name == SystemConfig::NAME_C_HOME_PAGE_BANNER_TYPE) {
                    $oldValueStr = SystemConfig::$cHomePageTypes[$oldValue] ?? '';
                    $newValueStr = SystemConfig::$cHomePageTypes[$newValue] ?? '';
                    $content .= "由【{$oldValueStr}】更改为【{$newValueStr}】";
                } else {
                    $content .= "由【{$oldValue}】更改为【{$newValue}】";
                }
            }
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($systemConfig->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 业务项目操作日志
     * @param string $scenario
     * @param TreatmentProject $new
     * @param TreatmentProject |null $old
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createTreatmentProjectLog(string $scenario, TreatmentProject $new, ?TreatmentProject $old = null): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($scenario) {
            case 'create':
            case 'edit':
                $newStatus = TreatmentProject::$statuss[$new->status];
                $optionStr = "【名称：{$new->name} 排序：{$new->sort} E看牙项目：{$new->tag_id} 状态：{$newStatus}】";
                if ($scenario == 'create') {
                    $type = LogMemberOp::TYPE_TREATMENT_PROJECT_CREATE;
                    $content = "新增业务项目;{$optionStr}";
                } else {
                    $type = LogMemberOp::TYPE_TREATMENT_PROJECT_UPDATE;
                    $oldStatus = TreatmentProject::$statuss[$old->status];
                    if (self::isEditModel($old, $new, ['name', 'sort', 'status'])) {// 存在修改
                        $content = "编辑业务项目;由【名称：{$old->name} 排序：{$old->sort} E看牙项目：{$old->tag_id} 状态：{$oldStatus}】更改为{$optionStr}";
                    }
                }
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_TREATMENT_PROJECT_DELETE;
                $content = "删除业务项目;【名称:{$new->name}】";
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 客户类型操作日志
     * @param string $scenario
     * @param PatientType $new
     * @param PatientType |null $old
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createPatientTypeLog(string $scenario, PatientType $new, ?PatientType $old = null): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($scenario) {
            case 'create':
            case 'edit':
                $newStatus = PatientType::$statuss[$new->status];
                $optionStr = "【名称：{$new->name} 排序：{$new->sort} 渠道：{$new->channel_id} 状态：{$newStatus}】";
                if ($scenario == 'create') {
                    $type = LogMemberOp::TYPE_PATIENT_TYPE_CREATE;
                    $content = "新增客户类型;{$optionStr}";
                } else {
                    $type = LogMemberOp::TYPE_PATIENT_TYPE_UPDATE;
                    $oldStatus = PatientType::$statuss[$old->status];
                    if (self::isEditModel($old, $new, ['name', 'sort', 'status'])) {// 存在修改
                        $content = "编辑客户类型;由【名称：{$old->name} 排序：{$old->sort} 渠道：{$old->channel_id} 状态：{$oldStatus}】更改为{$optionStr}";
                    }
                }
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_PATIENT_TYPE_DELETE;
                $content = "删除客户类型;【名称:{$new->name}】";
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 代言人操作日志
     * @param string $scenario
     * @param Spoker $new
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createSpokerLog(string $scenario, Spoker $new): ?LogMemberOp
    {
        if ($scenario != 'examine') {
            return null;
        }
        $newStatus = Spoker::$statuss[$new->status];
        $optionStr = "【代言人：{$new->name} 代言人手机号：{$new->mobile} 审核状态状态：{$newStatus}】";
        $type = LogMemberOp::TYPE_SPOKER_EXAMINE;
        $content = "代言人审核;{$optionStr}";
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 客户操作日志
     * @param string $scenario
     * @param Patient $new
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createPatientLog(string $scenario, Patient $new): ?LogMemberOp
    {
        $content = '';
        $type = 0;
        switch ($scenario) {
            case 'connect':
                $optionStr = "【名称：{$new->name} 手机号：{$new->mobile}】";
                $type = LogMemberOp::TYPE_PATIENT_CONNECT;
                $content = "客户关联;{$optionStr}";
                break;
            case 'delete':
                $type = LogMemberOp::TYPE_PATIENT_DELETE;
                $content = "删除客户;【名称:{$new->name}】";
                break;
            default:
                break;
        }
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }

    /**
     * 客户意见操作日志
     * @param string $scenario
     * @param UserFeedback $new
     * @return LogMemberOp|null
     * @throws \Exception
     */
    public static function createUserReplyLog(string $scenario, UserFeedback $new): ?LogMemberOp
    {
        if ($scenario != 'reply') {
            return null;
        }
        $optionStr = "【回复内容：{$new->reply_content} 反馈内容：{$new->content} 回复人员：{$new->reply_member_id}】";
        $type = LogMemberOp::TYPE_USER_REPLY;
        $content = "客户意见回复;{$optionStr}";
        if (empty($content) || empty($type)) {
            return null;
        }
        return self::create($new->id, $content, $type, Yii::$app->user->identity->member_id);
    }
}